package juegos;

import java.util.Vector;

import estrategias.AEstrella;
/**
 * 
 * @author Roberto(work in progress)
 * faltan algunos operadores(dolor) y generar hijos
 */
public class NodoJapos extends Nodo{
	/**
	 * Barca: 0 orilla inicial, 1 orilla destino
	 */
	private int barca;
	/**
	 * Padre: 0 orilla inicial, 1 orilla destino
	 */
	private int padre;
	/**
	 * Madre: 0 orilla inicial, 1 orilla destino
	 */
	private int madre;
	/**
	 * Policia: 0 orilla inicial, 1 orilla destino
	 */
	private int policia;
	/**
	 * Hijo1: 0 orilla inicial, 1 orilla destino
	 */
	private int hijo1;
	/**
	 * Hijo2: 0 orilla inicial, 1 orilla destino
	 */
	private int hijo2;
	/**
	 * Hija1: 0 orilla inicial, 1 orilla destino
	 */
	private int hija1;
	/**
	 * hija2: 0 orilla inicial, 1 orilla destino
	 */
	private int hija2;
	/**
	 * Ladron: 0 orilla inicial, 1 orilla destino
	 */
	private int ladron;
	
	
	/**
	 * Constructora de la clase
	 */
	public NodoJapos(){
		this.barca=0;
		this.camino="Estado Inicial, ";
		this.coste=0;
		this.calculaEstado();
		this.hija1=0;
		this.hija2=0;
		this.hijo1=0;
		this.hijo2=0;
		this.informado=false;
		this.ladron=0;
		this.madre=0;
		this.padre=0;
		this.policia=0;
		this.profundidad=0;
		this.calculaHeur();
		
	}
	/**
	 * Contructora con parametros
	 * 
	 * @param bar valor que indica donde esta la barca
	 * @param pa valor que indica donde esta el padre
	 * @param ma valor que indica donde esta la madre
	 * @param pol valor que indica donde esta el policia
	 * @param lad valor que indica donde esta el ladron
	 * @param h1 valor que indica donde esta el hijo1
	 * @param h2 valor que indica donde esta el hijo2
	 * @param ha1 valor que indica donde esta la hija 1
	 * @param ha2 valor que indica donde esta la hija2
	 * @param op operador a usar
	 * @param c camino hasta este nodo
	 * @param costeCamino coste del camino hasta ahora
	 * @param profundidad profundidad del nodo
	 */
	public NodoJapos(int bar,int pa, int ma, int pol, int lad, int h1, int h2,int ha1,int ha2,int op,String c, int costeCamino, int profundidad){
		this.barca=bar;
		this.coste=costeCamino+1;
		this.calculaEstado();
		this.hija1=ha1;
		this.hija2=ha2;
		this.hijo1=h1;
		this.hijo2=h2;
		this.informado=false;
		this.ladron=lad;
		this.madre=ma;
		this.padre=pa;
		this.policia=pol;
		this.profundidad=profundidad+1;
		this.calculaHeur();
		//Aqui van a ir mas operadores que la ostia.
		String mov;
		switch (op){
		case 1: mov = (" muevePadre,"); break;
		case 2: mov = (" mueveMadre,"); break;
		case 3: mov = (" muevePadreMadre,"); break;
		case 4: mov = (" muevePolicia,"); break;
		case 5: mov = (" muevePadreHijo1,"); break;
		case 6: mov = (" muevePadreHijo2,"); break;
		case 7: mov = (" mueveMadreHija1,"); break;
		case 8: mov = (" mueveMadreHija2,");break;
		case 9: mov = (" muevePoliciaHijo1,");break;
		case 10: mov = (" muevePoliciaHijo2,");break;
		case 11: mov = (" muevePoliciaHija1,");break;
		case 12: mov = (" muevePoliciaHija2,");break;
		case 13: mov = (" muevePoliciaLadron,");break;
		default: mov = ("No existe ese movimiento");
		}
		this.camino = (c + mov);
	}
	
	/**
	 * Establece el estado final
	 */
	public void setFinal(){
		this.barca=1;
		this.hija1=1;
		this.hija2=1;
		this.hijo1=1;
		this.hijo2=1;
		this.ladron=1;
		this.madre=1;
		this.padre=1;
		this.policia=1;
		this.coste = 0;
		this.profundidad=0;
		this.camino = "Desde estado final->";
		this.calculaEstado();
		this.calculaHeur();
	}
	// solo codificamos los operadores posibles por que hay algunos que no se van a poder dar
	
	/**
	 * Operador que mueve al padre
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePadre(){
		NodoJapos nuevo=null;
		if ((this.barca==this.padre)&&(this.madre!=this.hijo1)&&(this.madre!=this.hijo2)&&(this.madre==this.hija1)&&(this.madre==this.hija2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,1,this.camino,this.coste,this.profundidad);
			if (nuevo.padre==1){
				nuevo.padre=0;
				nuevo.barca=0;
			}
			else{
				nuevo.padre=1;
				nuevo.barca=1;
			}
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		}
		return nuevo;
	}
	
	/**
	 * Operador que mueve a la madre
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos mueveMadre(){
		NodoJapos nuevo=null;
		if ((this.barca==this.madre)&&(this.padre!=this.hija1)&&(this.padre!=this.hija2)&&(this.padre==this.hijo1)&&(this.padre==this.hijo2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,2,this.camino,this.coste,this.profundidad);
			if (nuevo.madre==1){
				nuevo.madre=0;
				nuevo.barca=0;
			}
			else{
				nuevo.madre=1;
				nuevo.barca=1;
			}
		
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		}
		return nuevo;
	}
	
	
	public NodoJapos muevePadreMadre(){
		NodoJapos nuevo=null;
		if ((this.barca==this.padre)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,3,this.camino,this.coste,this.profundidad);
			if (nuevo.padre==1){
				nuevo.padre=0;
				nuevo.madre=0;
				nuevo.barca=0;
			}
			else{
				nuevo.padre=1;
				nuevo.madre=1;
				nuevo.barca=1;
			}
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		}
		return nuevo;
	}
	
	/**
	 * Operador que mueve al policia
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePolicia(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.padre!=this.ladron)&&(this.madre!=this.ladron)&&(this.hijo1!=this.ladron)&&(this.hijo2!=this.ladron)&&(this.hija1!=this.ladron)&&(this.hija2!=this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,4,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		}
		return nuevo;
	}
	
	/**
	 * Operador que mueve al padre y al hijo 1
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePadreHijo1(){
		NodoJapos nuevo=null;
		if ((this.barca==this.padre)&&(this.barca==this.hijo1)&&(this.madre!=this.hijo2)&&(this.madre==this.hija1)&&(this.madre==this.hija2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,5,this.camino,this.coste,this.profundidad);
			if (nuevo.padre==1){
				nuevo.padre=0;
				nuevo.barca=0;
				nuevo.hijo1=0;
			}
			else{
				nuevo.padre=1;
				nuevo.barca=1;
				nuevo.hijo1=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	
	/**
	 * Operador que mueve al padre y al hijo 2
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePadreHijo2(){
		NodoJapos nuevo=null;
		if ((this.barca==this.padre)&&(this.barca==this.hijo2)&&(this.madre!=this.hijo1)&&(this.madre==this.hija1)&&(this.madre==this.hija2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,6,this.camino,this.coste,this.profundidad);
			if (nuevo.padre==1){
				nuevo.padre=0;
				nuevo.barca=0;
				nuevo.hijo2=0;
			}
			else{
				nuevo.padre=1;
				nuevo.barca=1;
				nuevo.hijo2=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	
	
	
	//********************************************/
	
	/**
	 * Operador que mueve a la madre y a la hija 1
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos mueveMadreHija1(){
		NodoJapos nuevo=null;
		if ((this.barca==this.madre)&&(this.barca==this.hija1)&&(this.padre!=this.hija2)&&(this.padre==this.hijo1)&&(this.padre==this.hijo2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,7,this.camino,this.coste,this.profundidad);
			if (nuevo.madre==1){
				nuevo.madre=0;
				nuevo.barca=0;
				nuevo.hija1=0;
			}
			else{
				nuevo.madre=1;
				nuevo.barca=1;
				nuevo.hija1=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	
	/**
	 * Operador que mueve a la madre y a la hija2
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos mueveMadreHija2(){
		NodoJapos nuevo=null;
		if ((this.barca==this.madre)&&(this.barca==this.hija2)&&(this.padre!=this.hija1)&&(this.padre==this.hijo1)&&(this.padre==this.hijo2)&&(this.policia==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,8,this.camino,this.coste,this.profundidad);
			if (nuevo.madre==1){
				nuevo.madre=0;
				nuevo.barca=0;
				nuevo.hija2=0;
			}
			else{
				nuevo.madre=1;
				nuevo.barca=1;
				nuevo.hija2=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	//**********************************************/
	
	/**
	 * Operador que mueve al policia y al hijo1
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePoliciaHijo1(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.barca==this.hijo1)&&(this.padre!=this.ladron)&&(this.madre!=this.ladron)&&(this.hijo2!=this.ladron)&&(this.hija1!=this.ladron)&&(this.hija2!=this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,9,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
				nuevo.hijo1=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
				nuevo.hijo1=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	/**
	 * Operador que mueve al policia y al hijo 2
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePoliciaHijo2(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.barca==this.hijo2)&&(this.padre!=this.ladron)&&(this.madre!=this.ladron)&&(this.hijo1!=this.ladron)&&(this.hija1!=this.ladron)&&(this.hija2!=this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,10,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
				nuevo.hijo2=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
				nuevo.hijo2=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	/**
	 * Operador que mueve al policia y a la hija 1
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePoliciaHija1(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.barca==this.hija1)&&(this.padre!=this.ladron)&&(this.madre!=this.ladron)&&(this.hijo1!=this.ladron)&&(this.hijo2!=this.ladron)&&(this.hija2!=this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,11,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
				nuevo.hija1=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
				nuevo.hija1=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	/**
	 * Operador que mueve al policia y a la hija 2
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePoliciaHija2(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.barca==this.hija2)&&(this.padre!=this.ladron)&&(this.madre!=this.ladron)&&(this.hijo1!=this.ladron)&&(this.hijo2!=this.ladron)&&(this.hija1!=this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,12,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
				nuevo.hija2=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
				nuevo.hija2=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
	
	/**
	 * Operador que mueve al policia y al ladron
	 * @return nuevo nodo si es posible el movimiento
	 */
	public NodoJapos muevePoliciaLadron(){
		NodoJapos nuevo=null;
		if ((this.barca==this.policia)&&(this.barca==this.ladron)){
			nuevo=new NodoJapos(this.barca,this.padre,this.madre,this.policia,this.ladron,this.hijo1,this.hijo2,this.hija1,this.hija2,13,this.camino,this.coste,this.profundidad);
			if (nuevo.policia==1){
				nuevo.policia=0;
				nuevo.barca=0;
				nuevo.ladron=0;
			}
			else{
				nuevo.policia=1;
				nuevo.barca=1;
				nuevo.ladron=1;	
			}
			
			nuevo.calculaHeur();
			nuevo.calculaEstado();
		
		
	}
		return nuevo;
	}
	
		
	
	/**
	 * Asigna al estado un valor
	 */
	public void calculaEstado(){
		this.estado=this.barca*100000000+this.padre*10000000+this.madre*1000000+this.policia*100000+this.hijo1*10000+this.hijo2*1000+this.hija1*100+this.hija2*10+this.ladron;
	
	}
	/**
	 * Como este juego no tiene heuristica la ponemos a -1
	 */
	public void calculaHeur(){
		this.vHeur = -1;
	}
	/**
	 * metodo que nos dice si estamos en un estado final
	 * @return true si es final, false en otro caso
	 */
	public boolean esFinal(){
		return ((this.barca==1)&&(this.padre==1)&&(this.madre==1)&&(this.policia==1)&&(this.ladron==1)&&(this.hija1==1)&&(this.hija2==1)&&(this.hijo1==1)&&(this.hijo2==1));
	}
	/**
	 * Metodo que genera todos los hijos del nodo actual
	 * @return vector con todos los nodos
	 */
	public Vector generaHijos(){
		Vector nuevo=new Vector(0,1);
		NodoJapos op1=this.muevePadre();
    	NodoJapos op2=this.mueveMadre();
    	NodoJapos op3=this.muevePolicia();
    	NodoJapos op4=this.muevePadreHijo1();
    	NodoJapos op5=this.muevePadreHijo2();
    	NodoJapos op6=this.mueveMadreHija1();
    	NodoJapos op7=this.mueveMadreHija2();
    	NodoJapos op8=this.muevePoliciaHijo1();
    	NodoJapos op9=this.muevePoliciaHijo2();
    	NodoJapos op10=this.muevePoliciaHija1();
    	NodoJapos op11=this.muevePoliciaHija2();
    	NodoJapos op12=this.muevePoliciaLadron();
    	NodoJapos op13=this.muevePadreMadre();
    	if (op1!=null) nuevo.addElement(op1);   	
        if (op2!=null) nuevo.addElement(op2);        
      	if (op3!=null) nuevo.addElement(op3);
      	if (op4!=null) nuevo.addElement(op4);
      	if (op5!=null) nuevo.addElement(op5); 
      	if (op6!=null) nuevo.addElement(op6); 
      	if (op7!=null) nuevo.addElement(op7); 
      	if (op8!=null) nuevo.addElement(op8); 
      	if (op9!=null) nuevo.addElement(op9); 
      	if (op10!=null) nuevo.addElement(op10); 
      	if (op11!=null) nuevo.addElement(op11); 
      	if (op12!=null) nuevo.addElement(op12);
      	if (op13!=null) nuevo.addElement(op13); 
      	
      		
        return nuevo;
	}
	
	
	
}
